define(['mbDomUtils', 'mbMarkerUtils'], function (mbDomUtils, mbMarkerUtils) {
    var $c = {};

    $c.showLayer = function (map, layerId) {
        if (!(typeof layerId === 'string') && layerId.layerId) {
            layerId = layerId.layerId;
        }
        map.setLayoutProperty(layerId, 'visibility', 'visible');
    };

    $c.hideLayer = function (map, layerId) {
        if (!(typeof layerId === 'string') && layerId.layerId) {
            layerId = layerId.layerId;
        }
        map.setLayoutProperty(layerId, 'visibility', 'none');
    };

    $c.defaultMBMapSetup = function (map, options, on3dReady) {

        map.options = options || $c.getDefaultMBMapOption();

        map.isMBMap = true;

        map.destroy = map.destroySelf = map.remove;
        map.remove = function (overlayList) {
            if (!(overlayList instanceof Array)) {
                overlayList = [overlayList];
            }
            (overlayList || []).forEach(function (overlay) {
                if (overlay && overlay.removeFromMap) {
                    overlay.removeFromMap({map: map});
                }
            });
        };

        map.baseElevation = 0;
        map.setBaseElevation = function (elev) {
            map.baseElevation = elev || 0;
        };

        function makeEmptyLayer(id, onAdd, onRender) {
            return {
                id: id,
                type: 'custom',
                renderingMode: '3d',
                onAdd: onAdd || function () {
                },
                render: onRender || function (gl, matrix) {
                }
            };
        }

        var layer3d = makeEmptyLayer('map_custom_3d_layer', function (bmap, gl) {
            if (on3dReady) {
                on3dReady(map, gl);
            }
        }, function (gl, matrix) {
            // gl.clear(gl.DEPTH_BUFFER_BIT);

        });

        map.on('style.load', function () {
            map._styleLoaded = true;
            map.addLayer(layer3d);
            map.fire('complete', map);
        });

        /******************************************************
         *
         * Custom Sheets
         *
         *****************************************************/
        map._customSheets = {};

        map._setCustomSheet = function (key, sheetText) {
            var sheet = map._customSheets[key];
            if (!sheet) {
                sheet = map._customSheets[key] = document.createElement('style');
            }
            sheet.innerHTML = sheetText;
            // moves the sheet element to the end if exists
            document.body.appendChild(sheet);
            map._customSheets[key] = sheet;
        };

        map._removeCustomSheet = function (key) {
            var sheet = null;
            if ((sheet = map._customSheets[key])) {
                sheet.remove();
            }
        };

        map._setCustomSheet('markerLabel', [
            '.mbmap_marker_label {',
            '   position: absolute;',
            '   padding: .75rem 1.25rem;',
            '   margin-bottom: 1rem;',
            // '   border-radius: .25rem;',
            '   background-color: white;',
            '   width: auto;',
            '   min-width: 4rem;',
            '   border-width: 0;',
            '   box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);',
            '   top: 0;',
            '   left: 0;',
            '   white-space: nowrap;',
            '}',
            '.mbmap_marker_label.slim {' +
            '   border: 1px solid blue;' +
            '   background-color: white;' +
            '   padding: 3px;' +
            '   font-size: 12px;' +
            '   line-height: 14px;' +
            '}' +
            '.mapbox-dist-marker {' +
            '   position: absolute;',
            '   top: 0;',
            '   left: 0;',
            '   font-size: 12px;' +
            '   border: 1px solid rgb(75, 75, 75);' +
            '   border-radius: 3px;' +
            '   height: 24px;' +
            '   line-height: 18px;' +
            '   padding: 2px 7px;' +
            '   box-shadow: rgb(153, 153, 153) 2px 2px 8px;' +
            '   white-space: nowrap;' +
            '   background-color: white;' +
            '}' +
            '.mapbox-area-marker {' +
            '   position: absolute;',
            '   top: 0;',
            '   left: 0;',
            '   font-size: 12px;' +
            '   border: 1px solid rgb(75, 75, 75);' +
            '   border-radius: 3px;' +
            '   height: 24px;' +
            '   line-height: 18px;' +
            '   padding: 2px 7px;' +
            '   box-shadow: rgb(153, 153, 153) 2px 2px 8px;' +
            '   white-space: nowrap;' +
            '   background-color: white;' +
            '}'
        ].join(' '));

        /******************************************************
         *
         * event dispatching
         *
         *****************************************************/
        var element = map.getContainer();
        if (element) {

            function bindContainerEvent(domEvent, fireEvent) {
                element.addEventListener(domEvent, function (e) {
                    var markerParent = mbDomUtils.getAncestorOfClass(e.target, '.mbmap_marker');
                    if (markerParent) {
                        var marker = markerParent._mbmarkerObject;
                        if (marker && marker.on && marker.fire) {
                            marker.fire(fireEvent, e)
                        }
                    }
                });
            }

            bindContainerEvent('click', 'click');
            bindContainerEvent('contextmenu', 'rightclick');
        }

        map.moveTo = function (lngLat) {
            map.flyTo({
                center: lngLat,
            });
        };

    };

    return $c;
});